# generate-exceptions: generate C++ files for xapian-letor's exception hierarchy.
#
# Copyright (C) 2003,2004,2006,2007,2008,2009,2011,2012,2013,2014,2015 Olly Betts
# Copyright (C) 2007 Richard Boulton
# Copyright (C) 2016 Ayush Tomar
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

use strict;
use exception_data qw(
    $copyright $generated_warning @baseclasses @classes %classcode
);
use File::Path qw(mkpath);

mkpath("include/xapian-letor");
open HDR, ">include/xapian-letor/letor_error.h" or die $!;
open DISPATCH, ">include/xapian-letor/letor_errordispatch.h" or die $!;

print HDR <<'EOF';
/** @file letor_error.h
 *  @brief Hierarchy of classes which xapian-letor can throw as exceptions.
 */
EOF

print HDR $generated_warning;
print DISPATCH $generated_warning;

print HDR $copyright;
print DISPATCH $copyright;

print HDR <<'EOF';

#ifndef XAPIAN_INCLUDED_LETOR_ERROR_H
#define XAPIAN_INCLUDED_LETOR_ERROR_H

#include <xapian.h>

#include <string>
#include <xapian/attributes.h>
#include <xapian/visibility.h>

namespace Xapian {

/** All exceptions thrown by xapian-letor are subclasses of Xapian::Error.
 *
 *  Xapian::Error is defined in xapian-core/include/xapian/error.h
 *  xapian-letor error subclasses simply derive from the infrastructure defined over there
 */

EOF

for (@classes) {
    chomp;
    my ($class, $parent, $synopsis, $description) = @{$_};
    $description //= '';
    if ($description ne '') {
	$description =~ s!^! *  !mg;
	$description =~ s! +$!!mg;
	$description = " *\n" . $description;
    }
    my $code = sprintf('\%03o', $classcode{$class});

    print DISPATCH "case '$code': throw Xapian::$class(msg, context, error_string);\n";

    print HDR <<EOF;

/** $synopsis
$description */
class XAPIAN_VISIBILITY_DEFAULT $class : public $parent {
  public:
    /** \@private \@internal
     *  \@brief Private constructor for use by remote backend.
     *
     *  \@param error_string_	Optional string describing error.  May be NULL.
     */
    $class(const std::string \&msg_, const std::string \&context_, const char * error_string_)
	: $parent(msg_, context_, "$code$class", error_string_) {}
    /** General purpose constructor.
     *
     *  \@param msg_		Message giving details of the error, intended
     *				for human consumption.
     *  \@param context_	Optional context information for this error.
     *  \@param errno_		Optional errno value associated with this error.
     */
    explicit $class(const std::string \&msg_, const std::string \&context_ = std::string(), int errno_ = 0)
	: $parent(msg_, context_, "$code$class", errno_) {}
    /** Construct from message and errno value.
     *
     *  \@param msg_		Message giving details of the error, intended
     *				for human consumption.
     *  \@param errno_		Optional errno value associated with this error.
     */
    $class(const std::string \&msg_, int errno_)
	: $parent(msg_, std::string(), "$code$class", errno_) {}
  protected:
    /** \@private \@internal
     *  \@brief Constructor for use by constructors of derived classes.
     */
    $class(const std::string \&msg_, const std::string \&context_, const char * type_, const char * error_string_)
	: $parent(msg_, context_, type_, error_string_) {}

    /** \@private \@internal
     *  \@brief Constructor for use by constructors of derived classes.
     */
    $class(const std::string \&msg_, const std::string \&context_, const char * type_, int errno_)
	: $parent(msg_, context_, type_, errno_) {}
};
EOF
}

print HDR <<'EOF';

}

#endif /* XAPIAN_INCLUDED_LETOR_ERROR_H */
EOF

print DISPATCH <<'EOF';
#endif /* DOXYGEN */
EOF

close HDR or die $!;
close DISPATCH or die $!;

# vim: set syntax=perl:
